-- ShareM
-- Created by chengb Nov/3/2015
-- 分享功能
-- 目前分享的途径包含了facebook、line、微信、微博，不论通过哪种途径进行分享，奖励都是一样的

module("ShareM", package.seeall);

-- 奖励待领取队列
local waitBonusQueue = {};

-- 奖励待领取队列长度上限
local MAX_WAIT_BONUS_NUM = 3;

-- 内部声明
local addToWaitBonusQueue;
local checkBonusQueue;
local removeFromWaitBonusQueue;
local whenShareSucc;
local whenShareImageDownloaded;
local whenShareBonus;
local whenReloginOk;
local whenLoginOk;

-- 初始化
function init()
    EventMgr.removeAll("ShareM");

    -- 关注facebook分享成功的事件
    EventMgr.register("ShareM", event.FB_SHARE_SUCC, whenShareSucc);

    -- 关注line分享成功事件
    EventMgr.register("ShareM", event.LINE_SHARE_SUCC, whenShareSucc);

    -- 关注微信分享成功事件
    EventMgr.register("ShareM", event.WECHAT_SHARE_SUCC, whenShareSucc);

    -- 关注微博分享成功事件
    EventMgr.register("ShareM", event.WEIBO_SHARE_SUCC, whenShareSucc);

    -- 关注分享图片下载成功事件
    EventMgr.register("ShareM", event.SHARE_IMAGE_DOWNLOAD_SUCC, whenShareImageDownloaded);

    -- 关注重连成功的事件
    EventMgr.register("ShareM", event.RELOGIN_OK, whenReloginOk);

    -- 关注登录成功的事件
    EventMgr.register("ShareM", event.LOGIN_OK ,whenLoginOk);

    -- 关注成功领取分享奖励的事件
    EventMgr.register("ShareM", event.SHARE_BONUS, whenShareBonus);
end

-- 获取今日已分享迷宫次数
function getTodayShareDungeonTimes()
    local fbShare = ME.user.dbase:query("fb_share_dungeon");
    if type(fbShare) ~= 'table' then
        return 0;
    end

    local serverTime = TimeM.getServerTime();
    if serverTime >= (fbShare.reset_time or 0) then
        -- 已经超过了重置时间
        return 0;
    end

    return fbShare["times"] or 0;
end

-- 计算分享的奖励
function calcShareBonus(shareType)
    local bonus = {};
    if shareType == SHARE_TYPE_DUNGEON then
        -- 迷宫分享
        local lastDungeonScore = ME.user.dbase:queryTemp("last_dungeon_score", {});
        local score = lastDungeonScore["score"];
        local dungeonId = lastDungeonScore["dungeon_id"];
        if type(score) ~= 'number' or type(dungeonId) ~= 'number' then
            trace("ShareM", "玩家没有通关迷宫，没有分享奖励可领取。");
            return {};
        end
        local sharedTimes = getTodayShareDungeonTimes();
        bonus = FormulaM.invoke("CALC_FB_SHARE_DUNGEON_BONUS", ME.user, sharedTimes, score, dungeonId);
    elseif shareType == SHARE_TYPE_SLIME then
        -- 冈布奥分享
        bonus = FormulaM.invoke("CALC_FB_SHARE_SLIME_BONUS", ME.user);
    elseif shareType == SHARE_TYPE_AIRSHIP then
        -- 飞艇分享
        bonus = FormulaM.invoke("CALC_FB_SHARE_AIRSHIP_BONUS", ME.user);
    else
        trace("ShareM", "暂不支持类型为%d的分享", shareType);
    end

    return bonus;
end

-- 分享成功的回调
function whenShareSucc(args)
    trace("ShareM", "whenShareSucc: args = %o", args);

    local shareType = args.shareType;

    if shareType == SHARE_TYPE_GAME then
        -- 目前游戏分享没有奖励
        return;
    end

    local args = {};

    if shareType == SHARE_TYPE_SLIME then
        -- 如果是冈布奥分享，需要带上冈布奥ID
        local petId = ME.user.dbase:queryTemp("gain_pet_id") or 0;
        args["pet_id"] = petId;
    elseif shareType == SHARE_TYPE_AIRSHIP then
        -- 飞艇分享，需要带上飞艇ID
        local shipId = ME.user.dbase:queryTemp("gain_ship_id") or 0;
        args["airship_id"] = shipId;
    end

    -- 先添加到队列中，等收到服务器成功的消息后再从队列中移除
    addToWaitBonusQueue(shareType, args);

    if Socket.isConnected() then
        -- 通知服务器领取奖励
        -- 由于需要记录分享的时间，如果在客户端记录可能会有时差，因此这里直接交给服务器处理
        trace("ShareM", "请求服务器领取分享奖励。");
        Operation.cmd_take_fb_share_bonus(shareType, args);
    else
        trace("ShareM", "网络连接已断开，等待重连后再领取奖励。");

        -- 如果在迷宫中，重连一下
        if DungeonM.isInDungeon() then
            LoginM.quiteReconnect();
        end
    end
end

function whenShareImageDownloaded()
    -- 关闭等待中界面
    closeCommunicatingForm();
end

-- 分享到微信（聊天界面）
-- @param sceneType 分享场景
-- @param shareType 分享类型
-- @param args      参数
function wechatShare(sceneType, shareType, args)
    if sceneType ~= WECHAT_SCENE_SESSION and
       sceneType ~= WECHAT_SCENE_FRIENDS then
        trace("ShareM", "不支持的分享场景：%s", tostring(sceneType));
        return false;
    end

    -- 如果与服务器的连接已断开，尝试重连
    if not Socket.isConnected() then
        LoginM.tryReconnect(getLocStr("warning_title"), getLocStr("disconnect_tip"));
        return false;
    end

    trace("ShareM", "wechatShare():sceneType = %d, shareType = %d, args = %o", sceneType, shareType, args);

    -- 检查是否可以跳转到微信
    if not canOpenWechat() then
        -- 弹提示
        showHint2(getLocStr("slime_note"), getLocStr("app_not_installed"), true);
        return false;
    end

    if isAndroidPlatform() or isIosPlatform() then
        if shareType == SHARE_TYPE_GAME or
           shareType == SHARE_TYPE_DUNGEON then
            -- 游戏链接分享、迷宫分享
            local desc = args.desc;
            local url  = args.url;
            local title = desc;

            assert(type(desc) == "string", "必须传入desc");
            assert(type(url)  == "string", "必须传入url");

            if isAndroidPlatform() then
                callJavaFuncWithClass("com.WechatDelegate", "sendLinkURL",
                    { url, title, desc, sceneType, shareType, },
                    "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V");
            elseif isIosPlatform() then
                callOCFuncWithClass("WechatWrap", "sendLinkURL", {
                    url       = url,
                    title     = title,
                    desc      = desc,
                    scene     = sceneType,
                    shareType = shareType,
                });
            end

            return true;
        elseif shareType == SHARE_TYPE_SLIME or
               shareType == SHARE_TYPE_AIRSHIP then
            -- 冈布奥图片分享、飞艇图片分享
            local image = args.image;

            assert(type(image) == "string", "必须传入image");

            if string.startWith(image, "http") == true then
                -- 传入的是图片地址
                if isAndroidPlatform() then
                    callJavaFuncWithClass("com.WechatDelegate", "sendImageURL",
                        { image, sceneType, shareType, }, "(Ljava/lang/String;II)V");
                elseif isIosPlatform() then
                    callOCFuncWithClass("WechatWrap", "sendImage", {
                        imageURL  = image,
                        scene     = sceneType,
                        shareType = shareType,
                    });
                end
            else
                local scaleSize = 150;              -- 缩略图参考尺寸
                local w = AlignM.frameSize.width;   -- 屏幕宽
                local h = AlignM.frameSize.height;  -- 屏幕高
                local scaleHeight = scaleSize;
                local scaleWidth  = math.ceil(scaleSize * (w / h));

                if isAndroidPlatform() then
                    callJavaFuncWithClass("com.WechatDelegate", "sendImage",
                        { image, scaleWidth, scaleHeight, sceneType, shareType, }, "(Ljava/lang/String;IIII)V");
                elseif isIosPlatform() then
                    callOCFuncWithClass("WechatWrap", "sendImage", {
                        image       = image,
                        scaleHeight = scaleHeight,
                        scaleWidth  = scaleWidth,
                        scene       = sceneType,
                        shareType   = shareType,
                    });
                end
            end

            return true;
        end
    end

    return false;
end

-- Line分享
function lineShare(url)
    -- 如果与服务器的连接已断开，尝试重连
    if not Socket.isConnected() then
        LoginM.tryReconnect(getLocStr("warning_title"), getLocStr("disconnect_tip"));
        return false;
    end

    openUrl(url);
    return true;
end

-- 检查待奖励队列是否为空，如果不为空尝试领取奖励
function checkBonusQueue()
    if #waitBonusQueue == 0 then
        return;
    end

    for _, info in ipairs(waitBonusQueue) do
        local shareType = info.shareType;
        local args      = info.args;
        trace("ShareM", "请求服务器领取分享奖励：shareType = %d, args = %o", shareType, args);
        Operation.cmd_take_fb_share_bonus(shareType, args);
    end
end

-- 重连成功的回调
function whenReloginOk()
    checkBonusQueue();
end

-- 登录成功的回调
function whenLoginOk()
    checkBonusQueue();
end

-- 成功领取分享奖励的回调
function whenShareBonus(args)
    trace("ShareM", "whenShareBonus: args = %o", args);

    -- 清空待奖励队列
    -- TODO SLIMEC-6110 这里正确的做法应该是每次只清除一条
    removeFromWaitBonusQueue();
end

-- 加入待奖励队列
function addToWaitBonusQueue(shareType, args)
    table.insert(waitBonusQueue, { shareType = shareType, args = args, });
    if #waitBonusQueue > MAX_WAIT_BONUS_NUM then
        -- 长度超过上限时，移除队列的第一个
        table.remove(waitBonusQueue, 1);
    end
    trace("ShareM", "addToWaitBonusQueue: waitBonusQueue = %o", waitBonusQueue);
end

-- 从待奖励队列中移除
function removeFromWaitBonusQueue(shareType)
    if #waitBonusQueue == 0 then
        return;
    end

    -- 没指定分享类型，则清空队列
    if shareType == nil then
        waitBonusQueue = {};
        trace("ShareM", "removeFromWaitBonusQueue: waitBonusQueue = %o", waitBonusQueue);
        return;
    end

    -- 移除待奖励队列
    local i = 1;
    while i <= #waitBonusQueue do
        local info = waitBonusQueue[i];
        if info.shareType == shareType then
            table.remove(waitBonusQueue, i);
        else
            i = i + 1;
        end
    end
    trace("ShareM", "removeFromWaitBonusQueue: shareType = %d, waitBonusQueue = %o", shareType, waitBonusQueue);
end

-- 微博分享
function weiboShare(shareType, image, text)
    -- 如果与服务器的连接已断开，尝试重连
    if not Socket.isConnected() then
        LoginM.tryReconnect(getLocStr("warning_title"), getLocStr("disconnect_tip"));
        return;
    end

    trace("ShareM", "weiboShare():shareType = %d, image = %s, text = %s", shareType, image, text);

    -- 检查是否可以跳转到微博
    if not canOpenWeibo() then
        -- 弹提示
        showHint2(getLocStr("slime_note"), getLocStr("app_not_installed"), true);
        return;
    end

    if isIosPlatform() then
        if string.startWith(image, "http") == true then
            -- 传的是图片地址
            callOCFuncWithClass("WeiboWrap", "shareImage", {
                shareType = shareType,
                imageURL  = image,
                text      = text,
            });
        else
            callOCFuncWithClass("WeiboWrap", "shareImage", {
                shareType = shareType,
                image     = image,
                text      = text,
            });
        end

        return true;
    elseif isAndroidPlatform() then
        if string.startWith(image, "http") == true then
            -- 传的是图片地址
            callJavaFuncWithClass("com.qcplay.WeiboDelegate", "shareImage", {text, "", image, shareType},
                "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
        else
            callJavaFuncWithClass("com.qcplay.WeiboDelegate", "shareImage", {text, image, "", shareType},
                "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
        end

        return true;
    end

    return false;
end

-- 判断是否可以跳转到微信
function canOpenWechat()
    if isIosPlatform() then
        return callOCFuncWithClass("WechatWrap", "isWXAppInstalled");
    elseif isAndroidPlatform() then
        return callJavaFuncWithClass("com.WechatDelegate", "isWXAppInstalled", {}, "()Z");
    end

    return false;
end

-- 判断是否可以跳转到微博
function canOpenWeibo()
    if isIosPlatform() then
        return callOCFuncWithClass("WeiboWrap", "isWeiboAppInstalled");
    elseif isAndroidPlatform() then
        return callJavaFuncWithClass("com.qcplay.WeiboDelegate", "isWeiboAppInstalled", {}, "()Z");
    end

    return false;
end

-- 获取国内平台的分享链接
function getCNShareUrl()
    if not _G["dislist"] or not _G["dislist"]["share_url"] then
        -- 没有配置分享链接，直接取安装包下载地址
        return getPackageDownloadUrl();
    end

    local url;
    if isAndroidPlatform() then
        url = _G["dislist"]["share_url"]["android"] or "";
    else
        url = _G["dislist"]["share_url"]["ios"] or "";
    end

    -- 对于雷霆版本，如果当前在游戏中，需要带上玩家标识符，用于跟踪新增用户来源
    if PUBLISH_PLATFORM == PUBLISH_TYPE_LT then
        local account = getGaming3rdAccount();
        if type(account) == "string" and sizeof(account) > 0 then
            local key = "leiting";
            local ac = MyRc4.encrypt(account, key);
            ac = MyBase64.encode(ac);
            url = url .. "?ac=" .. ac;
        end
    end

    return url;
end

-- 抽取一张微博迷宫分享的图片地址
function fetchWeiboShareDungeonImage()
    local index = math.random(1, #WEIBO_SHARE_DUNGEON_IMAGES);
    local imageName = WEIBO_SHARE_DUNGEON_IMAGES[index];

    -- 如果不是ios平台，需要使用http格式的地址
    -- 安卓模拟器上使用https访问会有问题，因此这里需要处理一下
    if not isIosPlatform() then
        imageName = string.gsub(imageName, "https", "http");
    end

    return imageName;
end


